
Free Information Xchange presents:

Star Wars Episode 1 Racer - CD crack by Static Vengeance - May 26th, 1999

REQUIREMENTS:
Full game install
W32Dasm & Hex editor

	With all the hype about the new Star Wars movie (episode 1) you just knew there were going to be
games based on it.  Star Wars Episode 1 Racer is just such a game.  The game requires a 3D accelerator
and makes good use of it as well!  With dual voodoo 2 cards the game looks fantasic and with all the 
options turned on (or on high) runs quit fast.  The cut scenes are very good and the game play is great
so this game is well worth the money to buy.  I just have two minor problems with this racer.  First, once
you've seen the animations (cut scene movies) you really don't need to seem them every time you play the
game.  Second is a little program bug so commonly found in todays games, and that is the copy protection
used.  Why do they always make you have the original CD in the drive just to play the darn game?  Like any
game you'll be playing alot you don't want to hunt down the original CD to play it.  Also if you have kids
you'll want to make sure the CD is protected from harm.  The best way to do that is not to have the game
require the CD!  With a little effort on your part and a little guidance on my part you'll be able to do
that with this game.
	If you install the game and run it you'll notice that you'll need to put the CD in the drive.  One
of the reasons this is needed is due to the fact that the music files and all of the animations are kept on
the CD to keep the game install size down.  Fair enough, but what if we kill the animations and copy the
music files to the hard drive?  Then we can track down the CD check and kill that as well.  We'll end up with
a cracked copy of the game we can play anytime without the need for the CD to be in the CD Rom drive.  So let's
get started on our quest.  Install the game and you'll see two exe files.  The first one is basicly a loader,
but it has some very important features.  When you first run the game it's the file racer.exe that let's you
choose your 3D card and resolution.  Otherwise you're limited the stock 640x480 @ 16 bit color.  Hey!, we've
got big monitors and high powered 3D cards and we want to use higher res, right?  So we'll need to kill the
CD check in that file.  The other file is of course the main game program called swep1rcr.exe and we'll need
to track down the CD check in that file as well.  So disassemble racer.exe and do the usual trick:
  Go up to the menu bar and select "Refs" and then "String Data Refs" from the drop down menu.  When the refs
pop-up box comes up, grab the slider bar and start scrolling down looking for anything that looks interesting.
Eventualy, if you're paying attention, you'll find a ref of "/LNCH099/Please insert the CD "  Double click on
that and you'll be put in the middle of some routine.  However this string comes up 3 times so you'll have to
look at the surounding code to see which one is the one that is the CD check.  So checking around a bit with
the second occurrance you'll see some interesting things:

  -- Program Code --
:00404856 8D95F0FEFFFF            lea edx, dword ptr [ebp+FFFFFEF0]
:0040485C 52                      push edx
:0040485D E8BE7D0000              call 0040C620
:00404862 83C408                  add esp, 00000008

* Possible StringData Ref from Data Obj ->"Star Wars: Episode I Racer\"
                                  |
:00404865 68ACCC4200              push 0042CCAC
:0040486A 8D85F0FEFFFF            lea eax, dword ptr [ebp+FFFFFEF0]
:00404870 50                      push eax
:00404871 E8AA7D0000              call 0040C620
:00404876 83C408                  add esp, 00000008

* Possible StringData Ref from Data Obj ->"v1.0"
                                  |
:00404879 68C8CC4200              push 0042CCC8
:0040487E 8D8DF0FEFFFF            lea ecx, dword ptr [ebp+FFFFFEF0]
:00404884 51                      push ecx
:00404885 E8967D0000              call 0040C620
:0040488A 83C408                  add esp, 00000008

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004048D5(U)
|
:0040488D 6A00                    push 00000000       <-- Push a 0 on the stack
:0040488F E80F570000              call 00409FA3       <-- First call instruction before the CD request
:00404894 83C404                  add esp, 00000004   <-- Fix stack due to push command
:00404897 85C0                    test eax, eax       <-- Test eax for value
:00404899 753C                    jne 004048D7        <-- Conditional jump before asking for the CD!!
:0040489B 6A01                    push 00000001

* Possible StringData Ref from Data Obj ->"/LNCH073/Error"
                                  |
:0040489D 68D0CC4200              push 0042CCD0
:004048A2 E844090000              call 004051EB
:004048A7 83C404                  add esp, 00000004
:004048AA 50                      push eax

* Possible StringData Ref from Data Obj ->"/LNCH099/Please insert the CD "    <-- What got us here and why
                                        ->"into your CD-ROM player and try "  <-- we're doing this
                                        ->"again."
                                  |
:004048AB 68E0CC4200              push 0042CCE0
:004048B0 E836090000              call 004051EB
:004048B5 83C404                  add esp, 00000004
:004048B8 50                      push eax
:004048B9 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BEh                 <-- Post a windows pop-up message box
                                  |
:004048BB FF1530344200            Call dword ptr [00423430]
:004048C1 89857CFDFFFF            mov dword ptr [ebp+FFFFFD7C], eax
:004048C7 83BD7CFDFFFF02          cmp dword ptr [ebp+FFFFFD7C], 00000002
:004048CE 7505                    jne 004048D5
:004048D0 E91E010000              jmp 004049F3                <-- Jump back up to the mystery call!!

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004048CE(C)
|
:004048D5 EBB6                    jmp 0040488D

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404899(C)
|
:004048D7 E831510000              call 00409A0D                       <-- We want to get at least this far
:004048DC 8985E4FDFFFF            mov dword ptr [ebp+FFFFFDE4], eax
:004048E2 83BDE4FDFFFF04          cmp dword ptr [ebp+FFFFFDE4], 00000004
:004048E9 7F40                    jg 0040492B

* Possible StringData Ref from Data Obj ->"/LNCH075/Star Wars: Episode I "
                                        ->"Racer"
                                  |
:004048EB 6828CD4200              push 0042CD28
:004048F0 E8F6080000              call 004051EB
  -- Continuing Program Code --

	That's interesting to me, first you have a call then, the code tests eax for a zero value.  If
eax is not zero the code jumps over asking for the CD!  However, if eax is zero then up comes a windows
message box asking for the CD.  Then the code checks to see your response and will either exit to windows
or loop back up to the mystery call!  Well, let's take a closer look at that call and see what it's doing:

* Referenced by a CALL at Address:
|:0040488F                                             <-- Only called once!
|
:00409FA3 55                      push ebp
:00409FA4 8BEC                    mov ebp, esp
:00409FA6 81EC10040000            sub esp, 00000410
:00409FAC E82FFFFFFF              call 00409EE0
:00409FB1 8885FCFEFFFF            mov byte ptr [ebp+FFFFFEFC], al
:00409FB7 C685FDFEFFFF00          mov byte ptr [ebp+FFFFFEFD], 00

* Possible StringData Ref from Data Obj ->":\"         <-- Pushes a pointer to ":\" as in "D:\"
                                  |
:00409FBE 6814ED4200              push 0042ED14
:00409FC3 8D85FCFEFFFF            lea eax, dword ptr [ebp+FFFFFEFC]
:00409FC9 50                      push eax
:00409FCA E851260000              call 0040C620
:00409FCF 83C408                  add esp, 00000008
:00409FD2 8D8DF4FCFFFF            lea ecx, dword ptr [ebp+FFFFFCF4]
:00409FD8 51                      push ecx
:00409FD9 E8CCFCFFFF              call 00409CAA
:00409FDE 83C404                  add esp, 00000004
:00409FE1 8D95FCFEFFFF            lea edx, dword ptr [ebp+FFFFFEFC]
:00409FE7 52                      push edx
:00409FE8 8D85F0FBFFFF            lea eax, dword ptr [ebp+FFFFFBF0]
:00409FEE 50                      push eax
:00409FEF E81C260000              call 0040C610
:00409FF4 83C408                  add esp, 00000008
:00409FF7 8D8DF4FCFFFF            lea ecx, dword ptr [ebp+FFFFFCF4]
:00409FFD 51                      push ecx
:00409FFE 8D95F0FBFFFF            lea edx, dword ptr [ebp+FFFFFBF0]
:0040A004 52                      push edx
:0040A005 E816260000              call 0040C620
:0040A00A 83C408                  add esp, 00000008
:0040A00D 8D85F0FBFFFF            lea eax, dword ptr [ebp+FFFFFBF0]
:0040A013 50                      push eax
:0040A014 E866FBFFFF              call 00409B7F
:0040A019 83C404                  add esp, 00000004
:0040A01C 85C0                    test eax, eax
:0040A01E 745A                    je 0040A07A
:0040A020 837D0800                cmp dword ptr [ebp+08], 00000000
:0040A024 744D                    je 0040A073
:0040A026 6A00                    push 00000000
:0040A028 6A00                    push 00000000
:0040A02A 6A00                    push 00000000
:0040A02C 6A00                    push 00000000
:0040A02E 6A00                    push 00000000
:0040A030 6804010000              push 00000104
:0040A035 8D8DF8FDFFFF            lea ecx, dword ptr [ebp+FFFFFDF8]
:0040A03B 51                      push ecx
:0040A03C 8D95FCFEFFFF            lea edx, dword ptr [ebp+FFFFFEFC]
:0040A042 52                      push edx

* Reference To: KERNEL32.GetVolumeInformationA, Ord:0177h    <-- Get the volume name of the drive
                                  |
:0040A043 FF1554324200            Call dword ptr [00423254]
:0040A049 85C0                    test eax, eax
:0040A04B 7422                    je 0040A06F
:0040A04D 8B4508                  mov eax, dword ptr [ebp+08]        <-- Pointer from getvolume call
:0040A050 50                      push eax                           <-- Push it on the stack
:0040A051 8D8DF8FDFFFF            lea ecx, dword ptr [ebp+FFFFFDF8]  <-- Pointer to known volume name
:0040A057 51                      push ecx                           <-- Push it on the stack
:0040A058 E803750000              call 00411560                      <-- Compare the two
:0040A05D 83C408                  add esp, 00000008
:0040A060 85C0                    test eax, eax
:0040A062 7507                    jne 0040A06B                       <-- eax=1 means no match
:0040A064 B801000000              mov eax, 00000001                  <-- Set up for passed CD check
:0040A069 EB11                    jmp 0040A07C                       <-- Jump to exit

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A062(C)
|
:0040A06B 33C0                    xor eax, eax                       <-- Failed volume comparison
:0040A06D EB0D                    jmp 0040A07C                       <-- Jump to exit

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A04B(C)
|
:0040A06F 33C0                    xor eax, eax                       <-- Had an error reading volume name
:0040A071 EB09                    jmp 0040A07C                       <-- Jump to exit

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A024(C)
|
:0040A073 B801000000              mov eax, 00000001                  <-- Set up for a pass
:0040A078 EB02                    jmp 0040A07C                       <-- Jump to exit

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A01E(C)
|
:0040A07A 33C0                    xor eax, eax                       <-- The CD check failed

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040A069(U), :0040A06D(U), :0040A071(U), :0040A078(U)
|
:0040A07C 8BE5                    mov esp, ebp
:0040A07E 5D                      pop ebp
:0040A07F C3                      ret                                <-- Return to the caller

	Alright, very simple here, the code get's the volume name of the drive, does a compare if
everything works out, eax is loaded with 00000001 and it returns.  If there is an error reading the
information or the volume doesn't match what it should, then eax is loaded with zero which means
the CD check failed.  Well, armed with this information we can go back up to the code at 0040488F
and change the call instruction to mov eax, 00000001 this will force the jne at 00404899 to always
be taken.  This patch allows racer.exe to function and bypasses the CD check.  One down and one to
go, on to the next half of this quest:
	To start we must now disassemble swep1rcr.exe and do the same trick as above.  This time, when
scrolling down the ref box you'll come across "swep1rcr.exe"  This is a good sign (when hunting down
CD checks) so double click it and you'll be in the middle of this routine:

* Referenced by a CALL at Addresses:
|:00423E70   , :00425456   
|
:00425500 81EC8C030000            sub esp, 0000038C
:00425506 B93B000000              mov ecx, 0000003B
:0042550B 33C0                    xor eax, eax
:0042550D 53                      push ebx
:0042550E 55                      push ebp
:0042550F 56                      push esi
:00425510 57                      push edi
:00425511 8DBC24AD010000          lea edi, dword ptr [esp+000001AD]
:00425518 F3                      repz
:00425519 AB                      stosd
:0042551A 66AB                    stosw
:0042551C AA                      stosb
:0042551D A1E4794B00              mov eax, dword ptr [004B79E4]
:00425522 85C0                    test eax, eax
:00425524 0F8467010000            je 00425691
:0042552A 8D442418                lea eax, dword ptr [esp+18]
:0042552E 50                      push eax

* Possible StringData Ref from Data Obj ->"swep1rcr.exe"      <-- What got us here
                                  |
:0042552F 680C7F4B00              push 004B7F0C

* Reference To: VERSION.GetFileVersionInfoSizeA, Ord:0001h    <-- Get info on this file
                                  |
:00425534 E8DB910700              Call 0049E714
:00425539 8BF0                    mov esi, eax
:0042553B 85F6                    test esi, esi
:0042553D 0F84AE000000            je 004255F1
:00425543 56                      push esi
:00425544 E8F79C0700              call 0049F240
:00425549 83C404                  add esp, 00000004
:0042554C 8BD8                    mov ebx, eax
:0042554E 53                      push ebx
:0042554F 56                      push esi
:00425550 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"swep1rcr.exe"
                                  |
:00425552 680C7F4B00              push 004B7F0C

* Reference To: VERSION.GetFileVersionInfoA, Ord:0000h    <-- Get more info on this file
                                  |
:00425557 E8B2910700              Call 0049E70E
:0042555C 85C0                    test eax, eax
:0042555E 0F8484000000            je 004255E8
:00425564 8D4C2414                lea ecx, dword ptr [esp+14]
:00425568 8D542410                lea edx, dword ptr [esp+10]
:0042556C 51                      push ecx
:0042556D 52                      push edx

* Possible StringData Ref from Data Obj ->"\VarFileInfo\Translation"
                                  |
:0042556E 68F07E4B00              push 004B7EF0
:00425573 53                      push ebx

* Reference To: VERSION.VerQueryValueA, Ord:000Ah
                                  |
:00425574 E88F910700              Call 0049E708
:00425579 85C0                    test eax, eax
:0042557B 746B                    je 004255E8
:0042557D 8B442410                mov eax, dword ptr [esp+10]
:00425581 33C9                    xor ecx, ecx
:00425583 33D2                    xor edx, edx
:00425585 668B4802                mov cx, word ptr [eax+02]
:00425589 668B10                  mov dx, word ptr [eax]
:0042558C 51                      push ecx
:0042558D 52                      push edx
:0042558E 8D8424A4020000          lea eax, dword ptr [esp+000002A4]

* Possible StringData Ref from Data Obj ->"\StringFileInfo\%04X%04X\FileVersion"
                                  |
:00425595 68C87E4B00              push 004B7EC8
:0042559A 50                      push eax

* Reference To: USER32.wsprintfA, Ord:0264h
                                  |
:0042559B FF15D0C14A00            Call dword ptr [004AC1D0]
:004255A1 83C410                  add esp, 00000010
:004255A4 8D4C2414                lea ecx, dword ptr [esp+14]
:004255A8 8D542410                lea edx, dword ptr [esp+10]
:004255AC 8D84249C020000          lea eax, dword ptr [esp+0000029C]
:004255B3 51                      push ecx
:004255B4 52                      push edx
:004255B5 50                      push eax
:004255B6 53                      push ebx

* Reference To: VERSION.VerQueryValueA, Ord:000Ah
                                  |
:004255B7 E84C910700              Call 0049E708
:004255BC 85C0                    test eax, eax
:004255BE 7428                    je 004255E8
:004255C0 8B7C2410                mov edi, dword ptr [esp+10]
:004255C4 83C9FF                  or ecx, FFFFFFFF
:004255C7 33C0                    xor eax, eax
:004255C9 8D94249C010000          lea edx, dword ptr [esp+0000019C]
:004255D0 F2                      repnz
:004255D1 AE                      scasb
:004255D2 F7D1                    not ecx
:004255D4 2BF9                    sub edi, ecx
:004255D6 8BC1                    mov eax, ecx
:004255D8 8BF7                    mov esi, edi
:004255DA 8BFA                    mov edi, edx
:004255DC C1E902                  shr ecx, 02
:004255DF F3                      repz
:004255E0 A5                      movsd
:004255E1 8BC8                    mov ecx, eax
:004255E3 83E103                  and ecx, 00000003
:004255E6 F3                      repz
:004255E7 A4                      movsb

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0042555E(C), :0042557B(C), :004255BE(C)
|
:004255E8 53                      push ebx
:004255E9 E8E29B0700              call 0049F1D0
:004255EE 83C404                  add esp, 00000004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042553D(C)
|
:004255F1 689C554D00              push 004D559C
:004255F6 6A50                    push 00000050
:004255F8 68C0F2E900              push 00E9F2C0

* Possible StringData Ref from Data Obj ->"CD Path"        <-- Hint, hint....
                                  |
:004255FD 68C07E4B00              push 004B7EC0
:00425602 E8A97C0700              call 0049D2B0
:00425607 83C410                  add esp, 00000010
:0042560A 85C0                    test eax, eax
:0042560C 7551                    jne 0042565F
:0042560E 68C0F2E900              push 00E9F2C0

* Reference To: KERNEL32.GetDriveTypeA, Ord:00DFh            <-- Commonly used call in CD checks
                                  |
:00425613 FF15C4C04A00            Call dword ptr [004AC0C4]
:00425619 83F805                  cmp eax, 00000005          <-- 05 is the value for CD Rom drives
:0042561C 7541                    jne 0042565F               <-- If not a CD the take this jump (failed)

* Possible StringData Ref from Data Obj ->".\data\config\default\"
                                  |
:0042561E 68843E4B00              push 004B3E84
:00425623 68C0F2E900              push 00E9F2C0
:00425628 8D8C24A4000000          lea ecx, dword ptr [esp+000000A4]

* Possible StringData Ref from Data Obj ->"%s\Gnome\%swheel.map"    <-- Check for this file
                                  |
:0042562F 68A87E4B00              push 004B7EA8
:00425634 51                      push ecx
:00425635 E816950700              call 0049EB50
:0042563A 83C410                  add esp, 00000010
:0042563D 8D94249C000000          lea edx, dword ptr [esp+0000009C]

* Possible StringData Ref from Data Obj ->"w"                       <-- Write to the CD
                                  |
:00425644 68A47E4B00              push 004B7EA4
:00425649 52                      push edx
:0042564A E8619B0700              call 0049F1B0
:0042564F 83C408                  add esp, 00000008
:00425652 85C0                    test eax, eax
:00425654 745A                    je 004256B0                       <-- Take this to continue with intro
:00425656 50                      push eax
:00425657 E8649A0700              call 0049F0C0
:0042565C 83C404                  add esp, 00000004

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0042560C(C), :0042561C(C)
|
:0042565F A16CB55000              mov eax, dword ptr [0050B56C]    
:00425664 6A10                    push 00000010

* Possible StringData Ref from Data Obj ->"BAD INSTALL"
                                  |
:00425666 68987E4B00              push 004B7E98

* Possible StringData Ref from Data Obj ->"Error:  Please reinstall program "  <-- Something we don't ever
                                        ->"from CD-ROM."                       <--  want to see!
                                  |
:0042566B 68447E4B00              push 004B7E44
:00425670 50                      push eax

* Reference To: USER32.MessageBoxA, Ord:0195h
                                  |
:00425671 FF15E0C14A00            Call dword ptr [004AC1E0]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004257D0(C)
|
:00425677 E854EAFFFF              call 004240D0
:0042567C 6A00                    push 00000000
:0042567E E88D930700              call 0049EA10
:00425683 83C404                  add esp, 00000004
:00425686 5F                      pop edi
:00425687 5E                      pop esi
:00425688 5D                      pop ebp
:00425689 5B                      pop ebx
:0042568A 81C48C030000            add esp, 0000038C
:00425690 C3                      ret                                <-- Return to the caller

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00425524(C)
|
:00425691 689C554D00              push 004D559C
:00425696 68C0F2E900              push 00E9F2C0
:0042569B E8B0940700              call 0049EB50
:004256A0 83C408                  add esp, 00000008
:004256A3 33C0                    xor eax, eax
:004256A5 5F                      pop edi
:004256A6 5E                      pop esi
:004256A7 5D                      pop ebp
:004256A8 5B                      pop ebx
:004256A9 81C48C030000            add esp, 0000038C
:004256AF C3                      ret                                <-- Return to the caller

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00425654(C)                                                        <-- Got via conditional jump from above
|
* Possible StringData Ref from Data Obj ->"100_0"                    <-- Partial volume name of the CD
                                  |
:004256B0 683C7E4B00              push 004B7E3C
:004256B5 8D442420                lea eax, dword ptr [esp+20]

* Possible StringData Ref from Data Obj ->"racer%s"
                                  |
:004256B9 68347E4B00              push 004B7E34
:004256BE 50                      push eax
:004256BF E88C940700              call 0049EB50

* Reference To: KERNEL32.GetVolumeInformationA, Ord:014Fh            <-- Get the volume of the disk
                                  |
:004256C4 8B2DC8C04A00            mov ebp, dword ptr [004AC0C8]

* Reference To: USER32.MessageBoxA, Ord:0195h
                                  |
:004256CA 8B1DE0C14A00            mov ebx, dword ptr [004AC1E0]
:004256D0 83C40C                  add esp, 0000000C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004257D6(U)
|
:004256D3 6A00                    push 00000000
:004256D5 6A00                    push 00000000
:004256D7 6A00                    push 00000000
:004256D9 6A00                    push 00000000
:004256DB 6A00                    push 00000000
:004256DD 8D8C2430010000          lea ecx, dword ptr [esp+00000130]
:004256E4 6880000000              push 00000080
:004256E9 51                      push ecx
:004256EA 68C0F2E900              push 00E9F2C0
:004256EF FFD5                    call ebp
:004256F1 85C0                    test eax, eax
:004256F3 0F849C000000            je 00425795
:004256F9 8D7C241C                lea edi, dword ptr [esp+1C]
:004256FD 83C9FF                  or ecx, FFFFFFFF
:00425700 33C0                    xor eax, eax
:00425702 8D54241C                lea edx, dword ptr [esp+1C]
:00425706 F2                      repnz
:00425707 AE                      scasb
:00425708 F7D1                    not ecx
:0042570A 83C1FE                  add ecx, FFFFFFFE
:0042570D 8D84241C010000          lea eax, dword ptr [esp+0000011C]
:00425714 51                      push ecx
:00425715 52                      push edx
:00425716 50                      push eax
:00425717 E8B4980700              call 0049EFD0
:0042571C 83C40C                  add esp, 0000000C
:0042571F 85C0                    test eax, eax
:00425721 7578                    jne 0042579B

* Possible StringData Ref from Data Obj ->".\data\config\default\"        <-- Partial path from the CD
                                  |
:00425723 68843E4B00              push 004B3E84
:00425728 68C0F2E900              push 00E9F2C0
:0042572D 8D8C24A4000000          lea ecx, dword ptr [esp+000000A4]

* Possible StringData Ref from Data Obj ->"%s\Gnome\%swheel.map"
                                  |
:00425734 68A87E4B00              push 004B7EA8
:00425739 51                      push ecx
:0042573A E811940700              call 0049EB50
:0042573F 83C410                  add esp, 00000010
:00425742 8D94249C010000          lea edx, dword ptr [esp+0000019C]

* Possible StringData Ref from Data Obj ->"\Gnome\Data\Anims\PlanetG.znm"  <-- The animation file to play
                                  |  
:00425749 68147E4B00              push 004B7E14
:0042574E 68C0F2E900              push 00E9F2C0

* Possible StringData Ref from Data Obj ->"%s%s"
                                  |
:00425753 6824254B00              push 004B2524
:00425758 52                      push edx
:00425759 E8F2930700              call 0049EB50
:0042575E 83C410                  add esp, 00000010
:00425761 8D84249C010000          lea eax, dword ptr [esp+0000019C]
:00425768 6A00                    push 00000000
:0042576A 50                      push eax
:0042576B E8F0AD0700              call 004A0560
:00425770 8BF0                    mov esi, eax
:00425772 83C408                  add esp, 00000008
:00425775 83FEFF                  cmp esi, FFFFFFFF
:00425778 7421                    je 0042579B
:0042577A 56                      push esi
:0042577B E830AD0700              call 004A04B0
:00425780 83C404                  add esp, 00000004
:00425783 3DE7141201              cmp eax, 011214E7
:00425788 56                      push esi
:00425789 7450                    je 004257DB               <-- Need to take this jump to continue on
:0042578B E820AC0700              call 004A03B0
:00425790 83C404                  add esp, 00000004
:00425793 EB06                    jmp 0042579B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004256F3(C)
|
* Reference To: KERNEL32.GetLastError, Ord:00F4h
                                  |
:00425795 FF15C0C04A00            Call dword ptr [004AC0C0]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00425721(C), :00425778(C), :00425793(U)
|
:0042579B 8D4C241C                lea ecx, dword ptr [esp+1C]
:0042579F 8D94249C020000          lea edx, dword ptr [esp+0000029C]
:004257A6 51                      push ecx

* Possible StringData Ref from Data Obj ->"Error:  Please insert CD-ROM '%s' "  <-- Not something we would
                                        ->"into drive."                         <--  ever want to see!
                                  |
:004257A7 68B07D4B00              push 004B7DB0
:004257AC 52                      push edx
:004257AD E89E930700              call 0049EB50
:004257B2 8B0D6CB55000            mov ecx, dword ptr [0050B56C]
:004257B8 83C40C                  add esp, 0000000C
:004257BB 8D84249C020000          lea eax, dword ptr [esp+0000029C]
:004257C2 6A31                    push 00000031

* Possible StringData Ref from Data Obj ->"CD ERROR"            <-- Says it all right here
                                  |
:004257C4 68A47D4B00              push 004B7DA4
:004257C9 50                      push eax
:004257CA 51                      push ecx
:004257CB FFD3                    call ebx
:004257CD 83F802                  cmp eax, 00000002
:004257D0 0F84A1FEFFFF            je 00425677
:004257D6 E9F8FEFFFF              jmp 004256D3

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00425789(C)
|
:004257DB E8D0AB0700              call 004A03B0

* Possible StringData Ref from Data Obj ->"\Gnome\"             <-- Partial path from the CD
                                  |
:004257E0 BF9C7D4B00              mov edi, 004B7D9C
:004257E5 83C9FF                  or ecx, FFFFFFFF
:004257E8 33C0                    xor eax, eax
:004257EA 83C404                  add esp, 00000004
:004257ED F2                      repnz
:004257EE AE                      scasb
:004257EF F7D1                    not ecx
:004257F1 2BF9                    sub edi, ecx
:004257F3 8BF7                    mov esi, edi
:004257F5 8BD1                    mov edx, ecx
:004257F7 BFC0F2E900              mov edi, 00E9F2C0
:004257FC 83C9FF                  or ecx, FFFFFFFF
:004257FF F2                      repnz
:00425800 AE                      scasb
:00425801 8BCA                    mov ecx, edx
:00425803 4F                      dec edi
:00425804 C1E902                  shr ecx, 02
:00425807 F3                      repz
:00425808 A5                      movsd
:00425809 8BCA                    mov ecx, edx
:0042580B 83E103                  and ecx, 00000003
:0042580E F3                      repz
:0042580F A4                      movsb
:00425810 5F                      pop edi
:00425811 5E                      pop esi
:00425812 5D                      pop ebp
:00425813 5B                      pop ebx
:00425814 81C48C030000            add esp, 0000038C
:0042581A C3                      ret                                <-- Return to the caller

	This routine, as long as it is, doesn't return any special value in eax so if you replace the
first instruction with a ret (C3) the CD check is effectively bypassed.  Now that the CD checks in both
exe files have been disabled or bypassed, it's time to address another problem with the game.
	The other problem with this game is:  All the music files and all of the animation files are
stored on the CD rom.  I can live without the all cut scenes, but I like the music.  So I tracked down
the routine that plays the animations and FiX'ed it so the game would skip them.  To do this you'll need
to go back to the refs box and look for a string that has something to do with the animation roiutnes
like "\Data\Anims"  If you double click on it you'll be in the middle of the routine that plays the
animation files for the game.  I will not show this routine as it's simply too long and would provide
little if any knowlegde.  However, starting with the ref, search backwards until you find the start of
the routine.  You will eventually see that this LONG routine starts at 4252A0 and is called from four
other locations.  If you trace it to the end, you'll see like the CD check this routine doesn't return
any special value either.  Replacing the first instruction with a ret code (C3) will disable all the
animations. Then if you copy the music directory to your hard drive the game will play just fine and
will no longer require you to have the CD online.  That is of course, the whole reason behind our
efforts and this tutorial.  The actual steps to crack Star Wars Episode 1 Racer are:

1.  Install the game
2.  Copy the "\Music" directory
   (from "CD":\Gnome\Data\wavs\ to your install directory in Data\wavs\)
3.  Copy the "\Anims" directory  <-- Skip if you want to kill anims anyways
   (from "CD":\Gnome\Data\ to your install directory in Data\)
4.  Make the following edits to the following files:

Edit Racer.exe
=============================================
Search for: E8 0F 57 00 00  at offset  18,575
Change to : B8 01 00 00 00

Edit swep1rcr.exe
=============================================
Search for: 81 EC 8C 03 00  at offset 149,760
Change to : C3 -- -- -- --

 - Optional: Kill the animation sequences:
Search for: 81 EC 0C 01 00  at offset 149,152
Change to : C3 -- -- -- --

For the French version: Edit Racer.exe
=============================================
Search for: E8 79 57 00 00  at offset  18,725
Change to : B8 01 00 00 00

Edit swep1rcr.exe
=============================================
Search for: 81 EC 8C 03 00  at offset 153,216
Change to : C3 -- -- -- --

 - Optional: Kill the animation sequences:
Search for: 81 EC 0C 01 00  at offset 152,608
Change to : C3 -- -- -- --


5.  Enjoy the game, graphics and races.

	You can always copy both the animation and music files to your hard drive, then you'll have a 100%
working copy of SW Episode 1 Racer on your hard drive.  The only problem is the game in this format takes up
478 megs!  This is the main reason I added the kill animation patch to the crack.  The final resault is a 268
meg install which is acceptable for this game and you'll have the music if you want it.  The music can also be
removed to free up another 76 megs, but you'll have to trace all the music routines and edit them out yourself.
That's as far as this tutorial goes, becuase this great racer has been FiX'ed!

Static Vengeance - FiX
